package com.google.code.chaotic.client.ui;

import java.util.Date;

import com.allen_sauer.gwt.log.client.Log;
import com.google.code.chaotic.client.ClientSessionManager;
import com.google.code.chaotic.client.LoginDto;
import com.google.code.chaotic.client.Util;
import com.google.code.chaotic.dto.UserType;
import com.google.code.chaotic.rpc.AuthSvc;
import com.google.code.chaotic.rpc.AuthSvcAsync;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class LoginEntryPoint implements EntryPoint {
	/**
	 * The message displayed to the user when the server cannot be reached or
	 * returns an error.
	 */
	private static final String SERVER_ERROR = "An error occurred while "
			+ "attempting to contact the server. Please check your network "
			+ "connection and try again.";

	public final static String HISTOCKEN_REGISTRATION = "registration";

	private final AuthSvcAsync authSvc = GWT.create(AuthSvc.class);

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		Log.setUncaughtExceptionHandler();

		// RootPanel usernameDiv = RootPanel.get("usernameBox");
		// Util.clearElement(usernameDiv.getElement());
		// TextBox usernameBox = new TextBox();
		// usernameBox.setStylePrimaryName("gaia le val");
		// usernameBox.setMaxLength(18);
		// usernameDiv.add(usernameBox);
		final TextBox usernameBox = TextBox.wrap(DOM //
				.getElementById("usernameBox"));

		// RootPanel passwordDiv = RootPanel.get("passwordBox");
		// Util.clearElement(passwordDiv.getElement());
		// PasswordTextBox passwordBox = new PasswordTextBox();
		// passwordBox.setStylePrimaryName("gaia le val");
		// passwordBox.setMaxLength(18);
		// passwordDiv.add(passwordBox);
		final PasswordTextBox passwordBox = PasswordTextBox.wrap(DOM //
				.getElementById("passwordBox"));

		final RootPanel loginButtonDiv = RootPanel.get("loginButton");
		Util.clearElement(loginButtonDiv.getElement());
		Button loginButton = new Button("Sign in");
		loginButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				authSvc.login(usernameBox.getValue(), passwordBox.getValue(),
						new AsyncCallback<LoginDto>() {
							@Override
							public void onSuccess(LoginDto result) {
								processLoginSuccess(result);
							}

							@Override
							public void onFailure(Throwable th) {
								Log.error(th.toString(), th);
							}
						});
			}
		});
		loginButton.setStylePrimaryName("gaia le button");
		loginButtonDiv.add(loginButton);

		RootPanel regSpan = RootPanel.get("registrationSpan");
		Util.clearElement(regSpan.getElement());
		Anchor regAnchor = new Anchor("Create an account");

		regAnchor.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				loadRegistrationPage();
				History.newItem(HISTOCKEN_REGISTRATION);
			}
		});
		regSpan.add(regAnchor);
		History.addValueChangeHandler(new ValueChangeHandler<String>() {
			@Override
			public void onValueChange(ValueChangeEvent<String> event) {
				processHistoryTocken(event.getValue());
			}

		});
		processHistoryTocken(History.getToken());
	}

	private void processLoginSuccess(LoginDto result) {
		ClientSessionManager instance = ClientSessionManager.getInstance();
		String sessionId = result.getSessionId();
		instance.setSessionId(sessionId);
		instance.setUserNoPass(result.getUserNoPass());

		// duration remembering login. 2 weeks in this example.
		final long DURATION = 1000 * 60 * 60 * 24 * 14;
		Date expires = new Date(System.currentTimeMillis() + DURATION);
		Cookies.setCookie("sid", sessionId, expires, null, "/", false);

		loadHomePage();
	}

	private void loadHomePage() {
		loadPage(new ChaosPanel());
	}

	private void loadRegistrationPage() {
		RegistrationPanel regPanel = new RegistrationPanel();		
		loadPage(regPanel);
	}

	private void loadPage(final Widget ui) {
		final RootPanel rootPanel = RootPanel.get("root");
		Util.clearElement(rootPanel.getElement());
		DeferredCommand.addCommand(new Command() {
			@Override
			public void execute() {
				rootPanel.add(ui, -1, -1);
			}
		});
	}

	private void processHistoryTocken(String string) {
		if (string.equals(HISTOCKEN_REGISTRATION))
			loadRegistrationPage();
	}
}
